#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include "libpq-fe.h"
#include "time.h"

static void exit_nicely(PGconn *conn){
    PQfinish(conn);
    exit(1);
}

// 通达信日K线数据结构
typedef struct 
{
    int date;    // 年月日，如：20191228
    int open;    // 开盘价的100倍
    int high;    // 最高价的100倍
    int low;     // 最低价的100倍
    int close;   // 收盘价的100倍
    float vol1;  // 成交额，元
    int vol2;    // 成交量，股
    int reserve; // 保留字
}dayrecordstruct;

int processDaily(char* trade_code, char* infile, char* outfile, PGconn* conn)
{
    FILE *finput, *foutput;
    dayrecordstruct dayrecord;
    
    printf("infile %s\n",infile);

    //if ((finput=fopen("..//data//sh512880.day","rb"))==NULL)
    if ((finput=fopen(infile,"rb"))==NULL)
    {
        printf("cant't open the input file");
        exit(0);
    }

    if ((foutput=fopen(outfile,"w"))==NULL)
    {
        printf("cant't open the out file");
        exit(0);
    }

    fprintf(foutput,"trade_date,open,high,low,close,vol1,vol2,reserve\n");

    char sql[] = "INSERT INTO etf.tradedaily(trade_date,trade_code,open,close,high,low,volume,amount) VALUES ($1,$2,$3,$4,$5,$6,$7,$8)";
    const char *stmtName = "stmt";
    PGresult *res;
    char *msg;
    char *paramValues[8];
    int paramLengths[8];
    int paramFormats[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    char tmpStr[100];
    
    //申请内存
    for(int p=0;p<=7;p++){
        paramValues[p] = (char *)malloc(100);            
    }


    res = PQprepare(conn, stmtName, sql, 8 , NULL);
    msg = PQresultErrorMessage(res);
    PQclear(res);
    if (strlen(msg) > 0)
    {
        printf("prepared failed/n");
        PQfinish(conn);
        exit(-1);
    }

    while(fread(&dayrecord,sizeof(dayrecordstruct),1,finput)==1)
    {
        printf("%d  %.3f  %.3f  %.3f  %.3f  %.3f  %d  %d\n",dayrecord.date, 
                                    (float)dayrecord.open/1000,
                                    (float)dayrecord.high/1000,
                                    (float)dayrecord.low/1000,
                                    (float)dayrecord.close/1000,
                                    dayrecord.vol1,
                                    dayrecord.vol2,
                                    dayrecord.reserve);
        fprintf(foutput,"%d,%.3f,%.3f,%.3f,%.3f,%.3f,%d,%d\n",dayrecord.date, 
                                    (float)dayrecord.open/1000,
                                    (float)dayrecord.high/1000,
                                    (float)dayrecord.low/1000,
                                    (float)dayrecord.close/1000,
                                    dayrecord.vol1,
                                    dayrecord.vol2,
                                    dayrecord.reserve);
        
        sprintf(paramValues[0],"%d",dayrecord.date);
        sprintf(paramValues[1],"%s",trade_code);
        sprintf(paramValues[2],"%.3lf", (float)dayrecord.open/1000);
        sprintf(paramValues[3],"%.3lf", (float)dayrecord.close/1000);        
        sprintf(paramValues[4],"%.3lf", (float)dayrecord.high/1000);        
        sprintf(paramValues[5],"%.3lf", (float)dayrecord.low/1000);        
        sprintf(paramValues[6],"%.3lf", dayrecord.vol1);
        sprintf(paramValues[7],"%d", dayrecord.vol2);
                
        paramLengths[0] = strlen(paramValues[0]);
        paramLengths[1] = strlen(paramValues[1]);
        paramLengths[2] = strlen(paramValues[2]);
        paramLengths[3] = strlen(paramValues[3]);
        paramLengths[4] = strlen(paramValues[4]);
        paramLengths[5] = strlen(paramValues[5]);
        paramLengths[6] = strlen(paramValues[6]);
        paramLengths[7] = strlen(paramValues[7]);

        res = PQexecPrepared(conn,stmtName,8, paramValues, paramLengths, paramFormats, 0);
        msg = PQresultErrorMessage(res);
        PQclear(res);

        if (strlen(msg) > 0)
        {
            printf("execute parepared statement failed at trade_date: %s trade_code: %s caused by %s \n",dayrecord.date, trade_code, msg);
        }

    }

    // 释放内存
    //free(paramValues);
    for(int p=0;p<=7;p++){
        free((char *)paramValues[p]);
        paramValues[p] = NULL;
    }

    PQfinish(conn);
    
    fclose(finput);
    fclose(foutput);

    return 0;
}

int main(int argc , char* argv[])
{   
    //数据库连接准备
    const char *conninfo;
    PGconn *conn;

    conninfo = "dbname=stock user=stock password=admin1234 host=localhost";
    conn = PQconnectdb(conninfo);
    if(PQstatus(conn) != CONNECTION_OK) {
        fprintf(stderr, "%s", PQerrorMessage(conn));
        exit_nicely(conn);
    }

    time_t start_time=0, end_time=0;
    // 打印任务开始时间
    time(&start_time);
    printf("job start...%ld\n",start_time);

    DIR * dir;
    struct dirent * ptr;
    int i;
    dir = opendir("..//data");
    while((ptr = readdir(dir)) != NULL)
    {
        if(strcmp(".", ptr->d_name) == 0 || 0 == strcmp("..", ptr->d_name) )
        {
            continue;
        }
        //只处理.day文件
        char *ptr1;
        char fname[80] = {0};
        char dayFileName[1024] = "..//data//";
        char txtFileName[1024] = "..//data//output//";
        //int sLen = 0;

        if (strrchr(ptr->d_name, '.') != NULL && strcmp(".day",strrchr(ptr->d_name,'.')) == 0)
        {
            printf("Process file: %s\n",ptr->d_name);
            ptr1 = strchr(ptr->d_name, '.');

            if (ptr != NULL) {
                strncpy(fname,ptr->d_name,ptr1 - ptr->d_name);
                strcat(dayFileName, fname);
                strcat(dayFileName, ".day");
                printf("day file name: %s\n",dayFileName);
                
                strcat(txtFileName, fname);
                strcat(txtFileName, ".txt");
                printf("text file name: %s\n",txtFileName);
                processDaily(fname, dayFileName, txtFileName, conn);
                
            } 
        }
    }
    closedir(dir);

    // 打印任务结束时间
    time(&end_time);
    printf("job end...%ld\n",end_time);
    printf("Time Used: %f\n",difftime(end_time,start_time));

    PQfinish(conn);
    return 0;
}